<template>
  <div 
    :class="[
      'bx-form-item',
      {
        'bx-form-item--error': validateState === 'error',
        'bx-form-item--validating': validateState === 'validating',
        'bx-form-item--success': validateState === 'success',
        'bx-form-item--required': isRequired,
        [`bx-form-item--${layout}`]: layout
      }
    ]"
  >
    <label 
      v-if="label || $slots.label"
      :class="[
        'bx-form-item__label',
        {
          [`bx-form-item__label--${labelAlign}`]: labelAlign
        }
      ]"
      :style="labelStyle"
    >
      <slot name="label">
        {{ label }}
        <span v-if="colon && label">:</span>
      </slot>
    </label>
    
    <div class="bx-form-item__content">
      <div class="bx-form-item__control">
        <slot></slot>
      </div>
      
      <div 
        v-if="validateMessage"
        class="bx-form-item__message"
      >
        {{ validateMessage }}
      </div>
      
      <div 
        v-if="help"
        class="bx-form-item__help"
      >
        {{ help }}
      </div>
    </div>
  </div>
</template>

<script>
import { ref, computed, inject, onMounted, onUnmounted, watch } from 'vue'

export default {
  name: 'BxFormItem',
  props: {
    prop: {
      type: String,
      default: ''
    },
    label: {
      type: String,
      default: ''
    },
    labelWidth: {
      type: [String, Number],
      default: ''
    },
    labelAlign: {
      type: String,
      default: '',
      validator: (value) => ['', 'left', 'right', 'top'].includes(value)
    },
    required: {
      type: Boolean,
      default: undefined
    },
    rules: {
      type: [Object, Array],
      default: () => []
    },
    help: {
      type: String,
      default: ''
    },
    colon: {
      type: Boolean,
      default: undefined
    }
  },
  setup(props) {
    const form = inject('bx-form', {})
    const validateState = ref('')
    const validateMessage = ref('')
    const initialValue = ref(undefined)

    const layout = computed(() => form.layout || 'vertical')
    const size = computed(() => form.size || 'medium')
    const labelAlign = computed(() => props.labelAlign || form.labelAlign || 'right')
    const colon = computed(() => props.colon !== undefined ? props.colon : form.colon)

    const labelStyle = computed(() => {
      const style = {}
      const labelWidth = props.labelWidth || form.labelWidth
      
      if (labelWidth && labelWidth !== 'auto') {
        const width = typeof labelWidth === 'number' ? `${labelWidth}px` : labelWidth
        style.width = width
        style.minWidth = width
      }
      
      return style
    })

    const fieldRules = computed(() => {
      const formRules = form.rules?.[props.prop] || []
      const itemRules = Array.isArray(props.rules) ? props.rules : [props.rules].filter(Boolean)
      return [...formRules, ...itemRules]
    })

    const isRequired = computed(() => {
      if (props.required !== undefined) {
        return props.required
      }
      return fieldRules.value.some(rule => rule.required)
    })

    const fieldValue = computed(() => {
      return form.model?.[props.prop]
    })

    const validate = async () => {
      if (!props.prop || !fieldRules.value.length) {
        return { valid: true }
      }

      validateState.value = 'validating'
      
      try {
        for (const rule of fieldRules.value) {
          const result = await validateRule(rule, fieldValue.value)
          if (!result.valid) {
            validateState.value = 'error'
            validateMessage.value = result.message
            return result
          }
        }
        
        validateState.value = 'success'
        validateMessage.value = ''
        return { valid: true }
      } catch (error) {
        validateState.value = 'error'
        validateMessage.value = error.message || '验证失败'
        return { valid: false, message: validateMessage.value }
      }
    }

    const validateRule = async (rule, value) => {
      // 必填验证
      if (rule.required) {
        if (value === undefined || value === null || value === '') {
          return { valid: false, message: rule.message || `${props.label}是必填项` }
        }
      }

      // 类型验证
      if (rule.type && value !== undefined && value !== null && value !== '') {
        const typeValidators = {
          string: (val) => typeof val === 'string',
          number: (val) => typeof val === 'number' && !isNaN(val),
          boolean: (val) => typeof val === 'boolean',
          array: (val) => Array.isArray(val),
          email: (val) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val),
          url: (val) => /^https?:\/\/.+/.test(val)
        }
        
        const validator = typeValidators[rule.type]
        if (validator && !validator(value)) {
          return { valid: false, message: rule.message || `${props.label}格式不正确` }
        }
      }

      // 长度验证
      if (rule.min !== undefined || rule.max !== undefined) {
        const len = typeof value === 'string' ? value.length : value
        if (rule.min !== undefined && len < rule.min) {
          return { valid: false, message: rule.message || `${props.label}长度不能少于${rule.min}` }
        }
        if (rule.max !== undefined && len > rule.max) {
          return { valid: false, message: rule.message || `${props.label}长度不能超过${rule.max}` }
        }
      }

      // 正则验证
      if (rule.pattern && value) {
        if (!rule.pattern.test(value)) {
          return { valid: false, message: rule.message || `${props.label}格式不正确` }
        }
      }

      // 自定义验证器
      if (rule.validator && typeof rule.validator === 'function') {
        try {
          const result = await rule.validator(value, rule)
          if (result !== true) {
            return { valid: false, message: result || rule.message || '验证失败' }
          }
        } catch (error) {
          return { valid: false, message: error.message || rule.message || '验证失败' }
        }
      }

      return { valid: true }
    }

    const reset = () => {
      if (props.prop && form.model) {
        form.model[props.prop] = initialValue.value
      }
      clearValidation()
    }

    const clearValidation = () => {
      validateState.value = ''
      validateMessage.value = ''
    }

    // 监听字段值变化，触发验证
    watch(fieldValue, () => {
      if (validateState.value === 'error') {
        validate()
      }
    })

    onMounted(() => {
      if (props.prop) {
        // 保存初始值
        initialValue.value = fieldValue.value
        
        // 注册到表单
        if (form.addField) {
          form.addField({
            prop: props.prop,
            validate,
            reset,
            clearValidation
          })
        }
      }
    })

    onUnmounted(() => {
      if (props.prop && form.removeField) {
        form.removeField(props.prop)
      }
    })

    return {
      validateState,
      validateMessage,
      layout,
      size,
      labelAlign,
      colon,
      labelStyle,
      isRequired,
      validate,
      reset,
      clearValidation
    }
  }
}
</script>

<style scoped>
.bx-form-item {
  margin-bottom: var(--bx-spacing-lg);
  font-family: var(--bx-font-family);
}

.bx-form-item--horizontal {
  display: flex;
  align-items: flex-start;
}

.bx-form-item--vertical {
  display: flex;
  flex-direction: column;
}

.bx-form-item--inline {
  display: inline-flex;
  flex-direction: column;
  margin-right: var(--bx-spacing-md);
  margin-bottom: var(--bx-spacing-md);
}

.bx-form-item__label {
  color: var(--bx-text-primary);
  font-weight: 500;
  line-height: 1.5;
  position: relative;
}

.bx-form-item--horizontal .bx-form-item__label {
  padding: 8px 12px 8px 0;
  flex-shrink: 0;
}

.bx-form-item--vertical .bx-form-item__label {
  margin-bottom: var(--bx-spacing-xs);
}

.bx-form-item__label--left {
  text-align: left;
}

.bx-form-item__label--right {
  text-align: right;
}

.bx-form-item__label--top {
  text-align: left;
}

.bx-form-item--required .bx-form-item__label::before {
  content: '*';
  color: rgba(255, 59, 48, 0.8);
  margin-right: 4px;
}

.bx-form-item__content {
  flex: 1;
  min-width: 0;
}

.bx-form-item__control {
  position: relative;
}

.bx-form-item__message {
  margin-top: var(--bx-spacing-xs);
  font-size: 12px;
  line-height: 1.4;
  color: rgba(255, 59, 48, 0.8);
  animation: bx-form-item-message-slide-in 0.3s ease-out;
}

.bx-form-item__help {
  margin-top: var(--bx-spacing-xs);
  font-size: 12px;
  line-height: 1.4;
  color: var(--bx-text-tertiary);
}

.bx-form-item--error .bx-form-item__control :deep(.bx-input),
.bx-form-item--error .bx-form-item__control :deep(.bx-select),
.bx-form-item--error .bx-form-item__control :deep(.bx-textarea) {
  border-color: rgba(255, 59, 48, 0.5);
}

.bx-form-item--success .bx-form-item__control :deep(.bx-input),
.bx-form-item--success .bx-form-item__control :deep(.bx-select),
.bx-form-item--success .bx-form-item__control :deep(.bx-textarea) {
  border-color: rgba(52, 199, 89, 0.5);
}

@keyframes bx-form-item-message-slide-in {
  0% {
    opacity: 0;
    transform: translateY(-8px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .bx-form-item--horizontal {
    flex-direction: column;
  }
  
  .bx-form-item--horizontal .bx-form-item__label {
    padding: 0 0 var(--bx-spacing-xs) 0;
    text-align: left;
  }
  
  .bx-form-item--inline {
    display: flex;
    margin-right: 0;
    margin-bottom: var(--bx-spacing-md);
  }
}
</style>

